package com.culturalCenter.dataCenter.schedule.activity;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.culturalCenter.dataCenter.Utils.ClassUtil;
import com.culturalCenter.dataCenter.Utils.RedisUtil;
import com.culturalCenter.dataCenter.Utils.RichTextUtil;
import com.culturalCenter.dataCenter.customEntity.ServicedNumber;
import com.culturalCenter.dataCenter.customEntity.activity.pull.*;
import com.culturalCenter.dataCenter.entity.Information;
import com.culturalCenter.dataCenter.entity.activity.*;
import com.culturalCenter.dataCenter.mapper.InformationMapper;
import com.culturalCenter.dataCenter.mapper.activity.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 定时任务_活动_拉取
 *
 * @Author zhao
 * @Date 2021-3-10 11:47
 */
@Component
@Slf4j
@Async("dataThreadExecutor")
public class ActivityDataPull {

    @Value("${tuchuang.hostname}")
    private String hostname;
    @Resource
    private RestTemplate restTemplate;
    @Resource
    private ActivityMapper activityMapper;
    @Resource
    private ActivityRoundMapper activityRoundMapper;
    @Resource
    private ActivitySigninRecordsMapper activitySigninRecordsMapper;
    @Resource
    private ActivityCommentMapper activityCommentMapper;
    @Resource
    private ActivityResourceMapper activityResourceMapper;
    @Resource
    private InformationMapper informationMapper;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private RedissonClient redisson;
    private final long size = 500;
    private long activity_timestamp1;
    private long activity_timestamp2;
    private long activity_timestamp3;
    private long activity_timestamp4;
    private long activity_timestamp5;
    private long activity_timestamp6;

    /**
     * 初始化时间戳
     */
    @PostConstruct
    public void initTimeStamp() {
        activity_timestamp1 = !redisUtil.redisTemplate.hasKey("activity_timestamp1") ? 0 : Long.parseLong(redisUtil.get("activity_timestamp1"));
        activity_timestamp2 = !redisUtil.redisTemplate.hasKey("activity_timestamp2") ? 0 : Long.parseLong(redisUtil.get("activity_timestamp2"));
        activity_timestamp3 = !redisUtil.redisTemplate.hasKey("activity_timestamp3") ? 0 : Long.parseLong(redisUtil.get("activity_timestamp3"));
        activity_timestamp4 = !redisUtil.redisTemplate.hasKey("activity_timestamp4") ? 0 : Long.parseLong(redisUtil.get("activity_timestamp4"));
        activity_timestamp5 = !redisUtil.redisTemplate.hasKey("activity_timestamp5") ? 0 : Long.parseLong(redisUtil.get("activity_timestamp5"));
        activity_timestamp6 = !redisUtil.redisTemplate.hasKey("activity_timestamp6") ? 0 : Long.parseLong(redisUtil.get("activity_timestamp6"));

        // for test
        // activity_timestamp1 = 0;
        // activity_timestamp2 = 0;
        // activity_timestamp3 = 0;
        // activity_timestamp4 = 0;
        // activity_timestamp5 = 0;
        // activity_timestamp6 = 0;
        // for (int i = 1; i <= 7; i++) {
        //     redisUtil.del("activity_lock" + i);
        // }
    }

    /**
     * 统一方法获取响应数据中的data
     *
     * @param url
     * @param param
     *
     * @return
     */
    public JSONObject getResponse(String url, Map<String, Object> param) {
        try {
            String interfaceUrl = url + "?" + ClassUtil.setParamString(param);
            String responseJson = restTemplate.getForObject(interfaceUrl, String.class, param);
            String data = JSON.parseObject(responseJson).getString("data");
            return JSON.parseObject(data);
        } catch (HttpServerErrorException e) {
            log.error("TCC综合管理平台服务端异常，请联系TCC相关人员");
            throw e;
        }
    }

    /**
     * 活动基本信息拉取（cdc_activity）
     */
    //@Scheduled(cron = "${cron.activityPull}")
    // @Scheduled(cron = "${cron.test}")
    public void pullActivity() {
        String lockKey = "activity_lock1";
        RLock redissonLock = redisson.getLock(lockKey);
        try {
            boolean locked = redissonLock.isLocked();
            if (!locked){
                redissonLock.lock();
            }
            log.info("'cdc_activity'开始拉取");

            String url = "/api/tcc-mes-service/client-api/culture/activity/listPage";
            Map<String, Object> param = new HashMap<>();
            param.put("updateTimestamp", activity_timestamp1);
            param.put("size", size);
            List<Activity> activityList = new ArrayList<>();
            long pages = 1;
            for (long current = 1; current <= pages; current++) {
                param.put("current", current);
                JSONObject data = getResponse(hostname + url, param);
                pages = Long.parseLong(data.getString("pages"));
                List<ActivityEntity> dataList = JSON.parseArray(data.getString("records"), ActivityEntity.class);
                if (CollectionUtils.isNotEmpty(dataList)) {
                    for (ActivityEntity dataElement : dataList) {
                        Activity activity = new Activity();
                        activity.setId(Long.toString(dataElement.getId()));
                        activity.setContactsBranch(dataElement.getOrgName());
                        activity.setDepartment(dataElement.getDepartmentName());
                        //？暂时活动名称=标题+副标题
                        activity.setActivityName(dataElement.getTitle() + dataElement.getSubTitle());
                        activity.setPicture(dataElement.getCoverImg());
                        activity.setLocation(dataElement.getAddress());
                        activity.setTotalNum(dataElement.getTotalQuota());
                        activity.setActivityType(dataElement.getCategoryName());
                        activity.setGroups(String.join(",", dataElement.getServicePerson()));
                        activity.setContacts(dataElement.getPrincipalName());
                        activity.setMobile(dataElement.getPrincipalPhone());

                        activity.setPublishTime(dataElement.getPublishTime());
                        activity.setSignUpBeginTime(dataElement.getRegisterStartTime());
                        activity.setSignUpEndTime(dataElement.getRegisterEndTime());

                        activity.setSignUpType(dataElement.getSignInType());
                        activity.setAgeLimit(dataElement.getAgeRestriction() == 0 ? "否" : "是");
                        activity.setAgeMin(dataElement.getAgeMin());
                        activity.setAgeMax(dataElement.getAgeMax());
                        activity.setGenderLimit(dataElement.getSexRestriction());

                        activity.setIntegralTag(dataElement.getIntegralTag());
                        activity.setCreateBy(dataElement.getCreateBy());

                        activity.setAuditBy(dataElement.getAuditBy());

                        activity.setViewCount(dataElement.getViewCount());
                        activity.setBranchId(Long.toString(dataElement.getOrgId()));
                        activity.setContent(RichTextUtil.getPlainText(dataElement.getDescribe()));
                        activity.setCollectCount(dataElement.getCollectCount());
                        activity.setAuditTime(dataElement.getAuditTime());
                        activity.setUpdateTime(dataElement.getUpdateTime());
                        activity.setDataStatus(dataElement.getDelTag());
                        String activityLabel = "";
                        List<Label> labels = dataElement.getLabels();
                        for (Label label : labels) {
                            if (!labels.get(0).equals(label)) {
                                activityLabel += "、";
                            }
                            activityLabel += label.getLabelName();
                        }
                        activity.setActivityLabel(activityLabel);
                        activityList.add(activity);
                    }
                    activityMapper.insertBatch(activityList);
                    redisUtil.set("activity_timestamp1",
                            Long.toString(activityList.stream().max(Comparator.comparing(Activity::getUpdateTime)).get().getUpdateTime().getTime()));
                    activityList.clear();
                }
            }
            log.info("cdc_activity拉取完毕");
        } finally {
            boolean locked = redissonLock.isLocked();
            if (locked){
                redissonLock.unlock();
            }
        }
    }

    /**
     * 活动场次拉取（cdc_activity_round）
     */
    //@Scheduled(cron = "${cron.activityPull}")
    // @Scheduled(cron = "${cron.test}")
    public void pullActivityRound() {
        String lockKey = "activity_lock2";
        RLock redissonLock = redisson.getLock(lockKey);
        try {
            boolean locked = redissonLock.isLocked();
            if (!locked){
                redissonLock.lock();
            }
            log.info("cdc_activity_round开始拉取");

            String url = "/api/tcc-mes-service/client-api/culture/activity/round/listPage";
            Map<String, Object> param = new HashMap<>();
            param.put("updateTimestamp", activity_timestamp2);
            param.put("size", size);
            long pages = 1;
            List<ActivityRound> activityRoundList = new ArrayList<>();
            for (long current = 1; current <= pages; current++) {
                param.put("current", current);
                JSONObject data = getResponse(hostname + url, param);
                pages = Long.parseLong(data.getString("pages"));
                List<ActivityRoundEntity> dataList = JSON.parseArray(data.getString("records"), ActivityRoundEntity.class);

                if (CollectionUtils.isNotEmpty(dataList)) {
                    for (ActivityRoundEntity dataElement : dataList) {
                        ActivityRound activityRound = new ActivityRound();
                        activityRound.setId(Long.toString(dataElement.getId()));
                        activityRound.setActivityId(Long.toString(dataElement.getActivityId()));
                        activityRound.setQuota(dataElement.getQuota());
                        activityRound.setStartTime(dataElement.getStartTime());
                        activityRound.setEndTime(dataElement.getEndTime());
                        activityRound.setSignInStartTime(dataElement.getSignInStartTime());
                        activityRound.setSignInEndTime(dataElement.getSignInEndTime());
                        activityRound.setPlaceNo(dataElement.getPlaceNo());
                        activityRound.setClassroomId(dataElement.getClassroomId());
                        activityRound.setUpdateTime(dataElement.getUpdateTime());

                        activityRoundList.add(activityRound);
                    }
                    activityRoundMapper.insertBatch(activityRoundList);
                    redisUtil.set("activity_timestamp2",
                            Long.toString(activityRoundList.stream().max(Comparator.comparing(ActivityRound::getUpdateTime)).get().getUpdateTime().getTime()));
                    activityRoundList.clear();
                }
            }
            log.info("cdc_activity_round拉取完毕");
        } finally {
            boolean locked = redissonLock.isLocked();
            if (locked){
                redissonLock.unlock();
            }
        }
    }

    /**
     * 拉取活动签到记录（cdc_activity_signIn_records）
     */
    //@Scheduled(cron = "${cron.activityPull}")
    // @Scheduled(cron = "${cron.test}")
    public void pullActivitySignInRecords() {
        String lockKey = "activity_lock3";
        RLock redissonLock = redisson.getLock(lockKey);
        try {
            boolean locked = redissonLock.isLocked();
            if (!locked){
                redissonLock.lock();
            }
            log.info("cdc_activity_signIn_records开始拉取");

            String url = "/api/tcc-mes-service/client-api/culture/activity/listSignInRecords";
            Map<String, Object> param = new HashMap<>();
            param.put("updateTimestamp", activity_timestamp3);
            param.put("size", size);
            long pages = 1;
            List<ActivitySigninRecords> activitySigningRecordsList = new ArrayList<>();
            for (long current = 1; current <= pages; current++) {
                param.put("current", current);
                JSONObject data = getResponse(hostname + url, param);
                pages = Long.parseLong(data.getString("pages"));
                List<ActivitySignInRecordsEntity> dataList = JSON.parseArray(data.getString("records"), ActivitySignInRecordsEntity.class);
                if (CollectionUtils.isNotEmpty(dataList)) {

                    for (ActivitySignInRecordsEntity dataElement : dataList) {
                        ActivitySigninRecords activitySigninRecords = new ActivitySigninRecords();
                        activitySigninRecords.setId(Long.toString(dataElement.getId()));
                        activitySigninRecords.setActivityId(Long.toString(dataElement.getActivityId()));
                        activitySigninRecords.setActivityRoundId(dataElement.getPeriodId());
                        activitySigninRecords.setUserId(dataElement.getUserId());
                        activitySigninRecords.setUsername(dataElement.getUsername());
                        activitySigninRecords.setRegisterTime(dataElement.getRegisterTime());
                        activitySigninRecords.setSignInTime(dataElement.getSignInTime());
                        activitySigninRecords.setApplyType(dataElement.getApplyType());
                        activitySigninRecords.setSignInSource(dataElement.getSignInSource());
                        activitySigninRecords.setUpdateTime(dataElement.getUpdateTime());

                        activitySigningRecordsList.add(activitySigninRecords);
                    }
                    activitySigninRecordsMapper.insertOrUpdateBatch(activitySigningRecordsList);
                    redisUtil.set("activity_timestamp3",
                            Long.toString(activitySigningRecordsList.stream().max(Comparator.comparing(ActivitySigninRecords::getUpdateTime)).get().getUpdateTime().getTime()));
                    activitySigningRecordsList.clear();
                }
            }

            log.info("cdc_activity_signIn_records拉取完毕");
        } finally {
            boolean locked = redissonLock.isLocked();
            if (locked){
                redissonLock.unlock();
            }
        }
    }

    /**
     * 拉取活动评价记录（cdc_activity_comment）
     */
    //@Scheduled(cron = "${cron.activityPull}")
    // @Scheduled(cron = "${cron.test}")
    public void pullEvaluationRecords() {
        String lockKey = "activity_lock4";
        RLock redissonLock = redisson.getLock(lockKey);
        try {
            boolean locked = redissonLock.isLocked();
            if (!locked){
                redissonLock.lock();
            }
            log.info("cdc_activity_comment开始拉取");

            String url = "/api/tcc-mes-service/client-api/culture/activity/listEvaluationRecords";
            Map<String, Object> param = new HashMap<>();
            param.put("updateTimestamp", activity_timestamp4);
            param.put("size", size);
            long pages = 1;
            List<ActivityComment> activityCommentList = new ArrayList<>();
            for (long current = 1; current <= pages; current++) {
                param.put("current", current);
                JSONObject data = getResponse(hostname + url, param);
                pages = Long.parseLong(data.getString("pages"));
                List<ActivityCommentEntity> dataList = JSON.parseArray(data.getString("records"), ActivityCommentEntity.class);
                if (CollectionUtils.isNotEmpty(dataList)) {

                    for (ActivityCommentEntity dataElement : dataList) {
                        ActivityComment activityComment = new ActivityComment();
                        activityComment.setId(Long.toString(dataElement.getId()));
                        activityComment.setActivityId(Long.toString(dataElement.getActivityId()));
                        activityComment.setUserId(Long.toString(dataElement.getUserId()));
                        activityComment.setStar(dataElement.getStarLevel());
                        switch (dataElement.getAuditStatus()) {
                            case 0:
                                activityComment.setReviewSituation("待审核");
                                break;
                            case 1:
                                activityComment.setReviewSituation("已审核");
                                break;
                            case 2:
                                activityComment.setReviewSituation("不通过");
                                break;
                            case 3:
                                activityComment.setReviewSituation("无需审核");
                                break;
                        }
                        activityComment.setContent(dataElement.getContent());
                        activityComment.setTime(dataElement.getEvaluationTime());
                        activityComment.setUpdateTime(dataElement.getUpdateTime());
                        activityComment.setLikeCount(dataElement.getLikeCount());

                        activityCommentList.add(activityComment);
                    }
                    activityCommentMapper.insertOrUpdateBatch(activityCommentList);
                    redisUtil.set("activity_timestamp4",
                            Long.toString(activityCommentList.stream().max(Comparator.comparing(ActivityComment::getUpdateTime)).get().getUpdateTime().getTime()));
                    activityCommentList.clear();
                }
            }

            log.info("cdc_activity_comment拉取完毕");
        } finally {
            boolean locked = redissonLock.isLocked();
            if (locked){
                redissonLock.unlock();
            }
        }
    }

    /**
     * 拉取活动精彩回顾（cdc_activity_resource）
     */
    //@Scheduled(cron = "${cron.activityPull}")
    // @Scheduled(cron = "${cron.test}")
    public void pullHighlights() {
        String lockKey = "activity_lock5";
        RLock redissonLock = redisson.getLock(lockKey);
        try {
            boolean locked = redissonLock.isLocked();
            if (!locked){
                redissonLock.lock();
            }
            log.info("cdc_activity_resource开始拉取");

            String url = "/api/tcc-mes-service/client-api/culture/activity/listHighlights";
            Map<String, Object> param = new HashMap<>();
            param.put("updateTimestamp", activity_timestamp5);
            param.put("size", size);
            long pages = 1;
            List<ActivityResource> activityResourceList = new ArrayList<>();
            for (long current = 1; current <= pages; current++) {
                param.put("current", current);
                JSONObject data = getResponse(hostname + url, param);
                pages = Long.parseLong(data.getString("pages"));
                List<ActivityResourceEntity> dataList = JSON.parseArray(data.getString("records"), ActivityResourceEntity.class);
                if (CollectionUtils.isNotEmpty(dataList)) {

                    for (ActivityResourceEntity dataElement : dataList) {
                        ActivityResource activityResource = new ActivityResource();
                        activityResource.setId(dataElement.getId());
                        activityResource.setActivityId(dataElement.getActivityId());
                        activityResource.setTitle(dataElement.getTitle());
                        activityResource.setCoverImg(dataElement.getCoverImg());
                        activityResource.setSourceURL(dataElement.getResourceUrl());
                        // 资源类型（?数据库暂时有三种，接口有两种）
                        if (ObjectUtils.isEmpty(dataElement.getResourceType())) {
                            activityResource.setType(null);
                        } else if (dataElement.getResourceType().equals("image")) {
                            activityResource.setType(1);
                        } else if (dataElement.getResourceType().equals("video")) {
                            activityResource.setType(3);
                        }
                        activityResource.setClickNum(dataElement.getViewCount());
                        activityResource.setUpdateTime(dataElement.getUpdateTime());

                        activityResourceList.add(activityResource);
                    }
                    activityResourceMapper.insertOrUpdateBatch(activityResourceList);
                    redisUtil.set("activity_timestamp5",
                            Long.toString(activityResourceList.stream().max(Comparator.comparing(ActivityResource::getUpdateTime)).get().getUpdateTime().getTime()));
                    activityResourceList.clear();
                }
            }

            log.info("cdc_activity_resource拉取完毕");
        } finally {
            boolean locked = redissonLock.isLocked();
            if (locked){
                redissonLock.unlock();
            }
        }
    }

    /**
     * 拉取并统计服务人数(cdc_activity_served_number)
     */
    //@Scheduled(cron = "${cron.activityPull}")
    // @Scheduled(cron = "${cron.test}")
    public void pullServiceNumber() {
        String lockKey = "activity_lock6";
        RLock redissonLock = redisson.getLock(lockKey);
        try {
            boolean locked = redissonLock.isLocked();
            if (!locked){
                redissonLock.lock();
            }
            log.info("cdc_activity_served_number开始拉取");

            /*
              获得branchId和date，然后根据这两个参数去请求获得数据
             */
            String url = "/api/tcc-mes-service/client-api/culture/statistics/list";
            Map<String, Object> param = new HashMap<>();
            /*
              如果库里没数据就拉所有的，否则只拉今天的
             */
            List<ServicedNumber> branchDays = activityMapper.getBranchDays(activityMapper.countServicedNumber() == 0 ? null : DateUtil.today());
            branchDays.forEach(branchDay -> {
                branchDay.setOnlineNumber(activityMapper.getOnlineNumberByBranchAndDay(branchDay.getBranchId(), DateUtil.formatDate(branchDay.getDate())));
                param.put("startTime", DateUtil.formatDate(branchDay.getDate()));
                param.put("endTime", DateUtil.formatDate(DateUtil.offsetDay(branchDay.getDate(), 1)));
                param.put("orgId", branchDay.getBranchId());
                JSONObject data = getResponse(hostname + url, param);
                List<ActivityServicedNumberData> result = JSON.parseArray(data.getString("records"), ActivityServicedNumberData.class);
                branchDay.setOfflineNumber(Integer.valueOf(result.get(0).getValue()));
                activityMapper.insertActivityServedNumber(branchDay);
            });

            log.info("cdc_activity_served_number拉取完毕");
        } finally {
            boolean locked = redissonLock.isLocked();
            if (locked){
                redissonLock.unlock();
            }
        }
    }

    /**
     * 文化资讯（cdc_information）
     */
    //@Scheduled(cron = "${cron.activityPull}")
    // @Scheduled(cron = "${cron.test}")
    public void pullInformation() {
        String lockKey = "activity_lock7";
        RLock redissonLock = redisson.getLock(lockKey);
        try {
            boolean locked = redissonLock.isLocked();
            if (!locked){
                redissonLock.lock();
            }
            log.info("cdc_information开始拉取");

            String url = "https://www.gz-arts.com/api/tcc-mes-service/client-api/pc/content/listPageByTime";
            Map<String, Object> param = new HashMap<>();
            param.put("timeFlag ",0);
            param.put("updateTimestamp", activity_timestamp6);
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add("orgId", "462673814262349824");
            HttpEntity httpEntity = new HttpEntity(headers);
            ResponseEntity<String> responseEntity = restTemplate.exchange(url + "?" + ClassUtil.setParamString(param), HttpMethod.GET, httpEntity, String.class);
            JSONObject result = JSON.parseObject(responseEntity.getBody());
            String data = result.getString("data");
            List<Information> informationList = JSONObject.parseArray(data, Information.class);
            if (CollectionUtils.isNotEmpty(informationList)) {
                int index = informationList.size() % 10000 == 0 ? informationList.size() / 10000 : informationList.size() / 10000 + 1;
                for (int i = 0; i < index; i++) {
                    informationMapper.insertOrUpdateBatch(informationList.stream().skip(i * 10000).limit(10000).collect(Collectors.toList()));
                    //TODO 图创数据问题：待修改
                    //图创返回的数据只有四个属性 无updatetime
                    if (Long.toString(informationList.stream().max(Comparator.comparing(Information::getUpdateTime)).get().getUpdateTime().getTime()) != null) {
                        redisUtil.set("activity_timestamp6",
                                Long.toString(informationList.stream().max(Comparator.comparing(Information::getUpdateTime)).get().getUpdateTime().getTime()));
                    }
                    informationList.clear();
                }
            }
            log.info("cdc_information拉取完毕");
        } catch (HttpServerErrorException e) {
            log.error("TCC综合管理平台服务端异常，请联系TCC相关人员");
            throw e;
        } finally {
            boolean locked = redissonLock.isLocked();
            if (locked){
                redissonLock.unlock();
            }
        }
    }

}
